/*
 * @Copyright: 2023 - 2023 www.hoperun.com Inc. All rights reserved.
 */

package com.lifeservice.util;

import com.lifeservice.common.config.MinioConfig;
import com.lifeservice.common.core.redis.RedisCache;
import com.lifeservice.common.utils.StringUtils;
import com.lifeservice.console.domain.LifeWxappConfig;
import com.lifeservice.console.service.ILifeWxappConfigService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author liu_yifeng
 * @function GenWxAppCode
 * @date 2023/3/30 17:52
 */
@Component
public class GenWxAppCodeUtil {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private MinioConfig minioConfig;
    @Autowired
    private MinioClient client;
    @Autowired
    private ILifeWxappConfigService wxappConfigService;
    private static final String AT_KEY = "AT_KEY_";

    private static final String WECHATCODE_KEY = "WECHATCODE_KEY_";

    private String wechatQrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
    private String wechatAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";

    public String genWechatCodeUrl(String tag) {
        return uploadWechatCode(getWechatQrcodeByRestTemplate(wechatQrcodeUrl + getAccessToken(), genBody("pages/index/index?tag=" + tag, "a=1")), tag);
    }

    public String getAccessToken() {
        LifeWxappConfig wxconfig = wxappConfigService.selectWxappConfig();
        String at = redisCache.getCacheObject(AT_KEY + wxconfig.getAppid());
        if (StringUtils.isNotEmpty(at)) {
            return at;
        }
        String url = String.format(wechatAccessTokenUrl, wxconfig.getAppid(), wxconfig.getAppSecret());
        Map<String, String> responseBody = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<Map<String, String>>() {
        }).getBody();
        if (responseBody == null || responseBody.get("errcode") != null) {
            // 获取失败
            System.out.println("getAccessToken失败：" + (responseBody == null ? "null" : responseBody.toString()));
            return null;
        }
        at = responseBody.get("access_token");
        redisCache.setCacheObject(AT_KEY + wxconfig.getAppid(), at, 60, TimeUnit.MINUTES);
        return at;
    }

    public Map<String, Object> genBody(String page, String scene) {
        Map<String, Object> ret = new HashMap<>();
        ret.put("page", page);
        ret.put("scene", scene);
        return ret;
    }

    public byte[] getWechatQrcodeByRestTemplate(String url, Map<String, Object> body) {
        if (url == null) {
            return null;
        }
        return restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, null), byte[].class).getBody();
    }

    public String uploadWechatCode(byte[] fileBytes, String tag) {
        if (null == fileBytes) {
            return null;
        }
        try {
            InputStream inputStream = new ByteArrayInputStream(fileBytes);
            FileOutputStream out = new FileOutputStream("d:\\test.png");
            byte[] buffer = new byte[8192];
            int bytesRead = 0;
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
            out.flush();
            inputStream.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String cacheKey = WECHATCODE_KEY + tag;
        String url = redisCache.getCacheObject(cacheKey);
        if (StringUtils.isNotEmpty(url)) {
            return url;
        }
        String contentType = "image/png";
        String allFileName = tag + ".png";
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(allFileName)
                .stream(new ByteArrayInputStream(fileBytes), fileBytes.length, -1)
                .contentType(contentType)
                .build();
        try {
            client.putObject(args);
        } catch (Exception e) {
            return null;
        }
        String weChatCodeObjectName = minioConfig.getBucketName() + "/" + allFileName;
        // 如果cdn不为空，则url为cdnurl
        url = StringUtils.isEmpty(minioConfig.getCdnName()) ? minioConfig.getUrl() + "/" + weChatCodeObjectName : minioConfig.getCdnName() + "/" + weChatCodeObjectName;
        redisCache.setCacheObject(cacheKey, url);
        return url;
    }
}
